{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 运行管理\n",
    "\n",
    "[![](https://gitee.com/mindspore/docs/raw/master/resource/_static/logo_source.png)](https://gitee.com/mindspore/docs/blob/master/docs/programming_guide/source_zh_cn/context.ipynb)&emsp;[![](https://gitee.com/mindspore/docs/raw/master/resource/_static/logo_notebook.png)](https://obs.dualstack.cn-north-4.myhuaweicloud.com/mindspore-website/notebook/master/programming_guide/mindspore_context.ipynb)&emsp;[![](https://gitee.com/mindspore/docs/raw/master/resource/_static/logo_modelarts.png)](https://authoring-modelarts-cnnorth4.huaweicloud.com/console/lab?share-url-b64=aHR0cHM6Ly9vYnMuZHVhbHN0YWNrLmNuLW5vcnRoLTQubXlodWF3ZWljbG91ZC5jb20vbWluZHNwb3JlLXdlYnNpdGUvbm90ZWJvb2svbW9kZWxhcnRzL3Byb2dyYW1taW5nX2d1aWRlL21pbmRzcG9yZV9jb250ZXh0LmlweW5i&imagename=MindSpore1.1.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 概述\n",
    "\n",
    "初始化网络之前要配置context参数，用于控制程序执行的策略。比如选择执行模式、选择执行后端、配置分布式相关参数等。按照context参数设置实现的不同功能，可以将其分为执行模式管理、硬件管理、分布式管理和维测管理等。\n",
    "\n",
    "> context接口详细介绍可以查看[mindspore.context](https://www.mindspore.cn/doc/api_python/zh-CN/master/mindspore/mindspore.context.html)。\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 执行模式管理\n",
    "\n",
    "MindSpore支持PyNative和Graph这两种运行模式：\n",
    "\n",
    "- `PYNATIVE_MODE`：动态图模式，将神经网络中的各个算子逐一下发执行，方便用户编写和调试神经网络模型。\n",
    "\n",
    "- `GRAPH_MODE`：静态图模式或者图模式，将神经网络模型编译成一整张图，然后下发执行。该模式利用图优化等技术提高运行性能，同时有助于规模部署和跨平台运行。\n",
    "\n",
    "### 模式选择\n",
    "\n",
    "通过配置context参数可以控制程序运行的模式。默认情况下，MindSpore处于PyNative模式。Graph和PyNative两种模式的区别主要有：\n",
    "\n",
    "- 使用场景：Graph模式需要一开始就构建好网络结构，然后框架做整图优化和执行，比较适合网络固定没有变化，且需要高性能的场景。而PyNative模式逐行执行算子，支持执行单算子、普通函数和网络，以及单独求梯度的操作。\n",
    "\n",
    "- 使用效率：理论上，MindSpore提供的算子同时支持Graph模式和PyNative模式，因此相同的网络和算子，分别在两个模式下执行时，精度效果是一致的。由于执行机理的差异，网络的执行性能会有不同。\n",
    "\n",
    "- 代码调试：在脚本开发和网络流程调试中，推荐使用PyNative模式进行调试。在PyNative模式下，可以方便地设置断点，获取网络执行的中间结果，也可以通过pdb的方式对网络进行调试。而Graph模式由于在构造函数里只是完成网络构造，实际没有执行，因此在`construct`函数里打断点无法获取对应算子的输出，只能等整网执行中指定对应算子的输出打印，在网络执行完成后进行查看。\n",
    "\n",
    "Graph模式和PyNative模式使用的是一种基于图表示的函数式IR，即MindIR，采用了接近于ANF函数式的语义。使用Graph模式时，将context中的运行模式设置为`GRAPH_MODE`，需要使用`nn.Cell`类，并且在`construct`函数中编写执行代码， 或者调用`@ms_function`装饰器。\n",
    "\n",
    "代码样例如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[ 4. 10. 18.]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import mindspore.nn as nn\n",
    "import mindspore.ops as ops\n",
    "from mindspore import context, Tensor\n",
    "\n",
    "context.set_context(mode=context.GRAPH_MODE, device_target=\"Ascend\")\n",
    "\n",
    "class Net(nn.Cell):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.mul = ops.Mul()\n",
    "\n",
    "    def construct(self, x, y):\n",
    "        return self.mul(x, y)\n",
    "\n",
    "x = Tensor(np.array([1.0, 2.0, 3.0]).astype(np.float32))\n",
    "y = Tensor(np.array([4.0, 5.0, 6.0]).astype(np.float32))\n",
    "\n",
    "net = Net()\n",
    "print(net(x, y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 模式切换\n",
    "\n",
    "MindSpore提供了静态图和动态图统一的编码方式，大大增加了静态图和动态图的可兼容性，用户无需开发多套代码，仅变更一行代码便可切换静态图/动态图模式。模式切换时，请留意目标模式的[约束](https://www.mindspore.cn/doc/note/zh-CN/master/static_graph_syntax_support.html)。例如，PyNative模式不支持数据下沉等。\n",
    "\n",
    "MindSpore处于Graph模式时，可以通过 `context.set_context(mode=context.PYNATIVE_MODE)`切换为PyNative模式；同样地，MindSpore处于PyNative模式时，可以通过`context.set_context(mode=context.GRAPH_MODE)`切换为Graph模式。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 硬件管理\n",
    "\n",
    "硬件管理部分主要包括`device_target`和`device_id`两个参数。\n",
    "\n",
    "- `device_target`： 用于设置目标设备，支持Ascend、GPU和CPU，可以根据实际环境情况设置。\n",
    "\n",
    "- `device_id`： 表示卡物理序号，即卡所在机器中的实际序号。如果目标设备为Ascend，且规格为N*Ascend（其中N>1，如8*Ascend），在非分布式模式执行的情况下，为了避免设备的使用冲突，可以通过设置`device_id`决定程序执行的device编号，该编号范围为：0 ~ 服务器总设备数量-1，服务器总设备数量不能超过4096，默认为设备0。\n",
    "\n",
    "> 在GPU和CPU上，设置`device_id`参数无效。\n",
    "\n",
    "代码样例如下：\n",
    "```python\n",
    "from mindspore import context\n",
    "context.set_context(device_target=\"Ascend\", device_id=6)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 分布式管理\n",
    "\n",
    "context中有专门用于配置并行训练参数的接口：`context.set_auto_parallel_context`，该接口必须在初始化网络之前调用。\n",
    "\n",
    "> 分布式并行训练详细介绍可以查看[分布式并行训练](https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/distributed_training_tutorials.html)。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 维测管理\n",
    "\n",
    "为了方便维护和定位问题，context提供了大量维测相关的参数配置，如采集profiling数据、异步数据dump功能和print算子落盘等。\n",
    "\n",
    "### 采集profiling数据\n",
    "\n",
    "系统支持在训练过程中采集profiling数据，然后通过profiling工具进行性能分析。当前支持采集的profiling数据包括：\n",
    "\n",
    "- `enable_profiling`：是否开启profiling功能。设置为True，表示开启profiling功能，从`enable_options`读取profiling的采集选项；设置为False，表示关闭profiling功能，仅采集`training_trace`。\n",
    "\n",
    "- `profiling_options`：profiling采集选项，取值如下，支持采集多项数据。 \n",
    "    - `result_path`：Profiling采集结果文件保存路径。该参数指定的目录需要在启动训练的环境上（容器或Host侧）提前创建且确保安装时配置的运行用户具有读写权限，支持配置绝对路径或相对路径（相对执行命令时的当前路径）。 \n",
    "    - `training_trace`：采集迭代轨迹数据，即训练任务及AI软件栈的软件信息，实现对训练任务的性能分析，重点关注数据增强、前后向计算、梯度聚合更新等相关数据，取值on/off。 \n",
    "    - `task_trace`：采集任务轨迹数据，即昇腾910处理器HWTS/AICore的硬件信息，分析任务开始、结束等信息，取值on/off。 \n",
    "    - `aicpu_trace`：采集aicpu数据增强的profiling数据。取值on/off。 \n",
    "    - `fp_point`：`training_trace`为on时需要配置。指定训练网络迭代轨迹正向算子的开始位置，用于记录前向算子开始时间戳。配置值为指定的正向第一个算子名字。当该值为空时，系统自动获取正向第一个算子名字。 \n",
    "    - `bp_point`：`training_trace`为on时需要配置。指定训练网络迭代轨迹反向算子的结束位置，用于记录反向算子结束时间戳。配置值为指定的反向最后一个算子名字。当该值为空时，系统自动获取反向最后一个算子名字。 \n",
    "    - `ai_core_metrics`取值如下：\n",
    "\n",
    "        - ArithmeticUtilization：各种计算类指标占比统计。\n",
    "\n",
    "        - PipeUtilization：计算单元和搬运单元耗时占比，该项为默认值。\n",
    "\n",
    "        - Memory：外部内存读写类指令占比。\n",
    "\n",
    "        - MemoryL0：内部内存读写类指令占比。\n",
    "\n",
    "        - ResourceConflictRatio：流水线队列类指令占比。\n",
    "\n",
    "代码样例如下：\n",
    "\n",
    "```python\n",
    "from mindspore import context\n",
    "context.set_context(enable_profiling=True, profiling_options= '{\"result_path\":\"/home/data/output\",\"training_trace\":\"on\"}')\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 保存MindIR\n",
    "\n",
    "通过`context.set_context(save_graphs=True)`来保存各个编译阶段的中间代码。\n",
    "\n",
    "被保存的中间代码有两种格式：一个是后缀名为`.ir`的文本格式，一个是后缀名为`.dot`的图形化格式。\n",
    "\n",
    "当网络规模较大时建议使用更高效的文本格式来查看，当网络规模不大时，建议使用更直观的图形化格式来查看。\n",
    "\n",
    "代码样例如下：\n",
    "\n",
    "```python\n",
    "from mindspore import context\n",
    "context.set_context(save_graphs=True)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> MindIR详细介绍可以查看[MindSpore IR（MindIR）](https://www.mindspore.cn/doc/note/zh-CN/master/design/mindspore/mindir.html)。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### print算子落盘\n",
    "\n",
    "默认情况下，MindSpore的自研print算子可以将用户输入的Tensor或字符串信息打印出来，支持多字符串输入，多Tensor输入和字符串与Tensor的混合输入，输入参数以逗号隔开。\n",
    "\n",
    "> Print打印功能可以查看[Print算子功能介绍](https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/custom_debugging_info.html#print)。\n",
    "\n",
    "- `print_file_path`：可以将print算子数据保存到文件，同时关闭屏幕打印功能。如果保存的文件已经存在，则会给文件添加时间戳后缀。数据保存到文件可以解决数据量较大时屏幕打印数据丢失的问题。\n",
    "\n",
    "代码样例如下：\n",
    "\n",
    "```python\n",
    "from mindspore import context\n",
    "context.set_context(print_file_path=\"print.pb\")\n",
    "```"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
